﻿Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports IntoNails.Models
Imports IntoNails.My.Resources

Namespace ViewModel
    Public Class IntoNailsViewModel
        Inherits SubWorkspaceViewModel

#Region "Declarations"

        Dim _activeUser As User



#End Region

#Region "Constructors"

        Public Sub New(ByVal user As User)
            Me.DisplayName = StringResources.INTONAILS_VIEWMODEL_DISPLAYNAME
            Me.ActiveUser = user

            Dim authorityCommands As List(Of AuthorizedCommandViewModel) = Me.ApplyCommands(user.AuthorityCode)
            Me.Commands = New ReadOnlyCollection(Of AuthorizedCommandViewModel)(authorityCommands)
        End Sub

#End Region

#Region "Delegate and Event"

        ' TODO: define an cancellable event, not this simble EventHandler
        Public Event UserLogout As EventHandler

        Protected Overridable Sub OnUserLogout(ByVal e As EventArgs)
            Dim exitHandler As EventHandler = Me.UserLogoutEvent
            If exitHandler IsNot Nothing Then
                exitHandler.Invoke(Me, e)
            End If
        End Sub

#End Region

#Region "Properties"

        ''' <summary>
        ''' Gets the user with authority, who controls the program
        ''' </summary>
        Public Property ActiveUser() As User
            Get
                Return _activeUser
            End Get
            Private Set(ByVal value As User)
                If ReferenceEquals(_activeUser, value) Then
                    Return
                End If
                _activeUser = value

                Me.OnPropertyChanged("ActiveUser")
            End Set
        End Property

#End Region

#Region "Workspaces"

        Private _activeWorkspace As SubWorkspaceViewModel
        Public Property ActiveWorkspace() As SubWorkspaceViewModel
            Get
                Return _activeWorkspace
            End Get
            Set(ByVal value As SubWorkspaceViewModel)
                If Object.ReferenceEquals(_activeUser, value) Then
                    Return
                End If

                _activeWorkspace = value
                Me.DisplayName = _activeWorkspace.DisplayName
                Me.OnPropertyChanged("ActiveWorkspace")
            End Set
        End Property

        Private _workspaces As ObservableCollection(Of SubWorkspaceViewModel)
        Public ReadOnly Property Workspaces() As ObservableCollection(Of SubWorkspaceViewModel)
            Get
                If _workspaces Is Nothing Then
                    _workspaces = New ObservableCollection(Of SubWorkspaceViewModel)()
                    AddHandler _workspaces.CollectionChanged, AddressOf Me.Workspace_CollectionChanged
                End If
                Return _workspaces
            End Get
        End Property

        Private Sub Workspace_CollectionChanged(ByVal sender As Object, ByVal e As NotifyCollectionChangedEventArgs)
            If e.NewItems IsNot Nothing AndAlso e.NewItems.Count > 0 Then
                For Each workspace As SubWorkspaceViewModel In e.NewItems
                    AddHandler workspace.RequestClose, AddressOf Workspace_RequestClose
                Next workspace
            End If

            If e.OldItems IsNot Nothing AndAlso e.OldItems.Count <> 0 Then
                For Each workspace As SubWorkspaceViewModel In e.OldItems
                    RemoveHandler workspace.RequestClose, AddressOf Workspace_RequestClose
                Next workspace
            End If
        End Sub

        Private Sub Workspace_RequestClose(ByVal sender As Object, ByVal e As EventArgs)
            Dim workspace As SubWorkspaceViewModel = TryCast(sender, SubWorkspaceViewModel)
            workspace.Dispose()
            Me.Workspaces.Remove(workspace)
        End Sub

#End Region

#Region "Commands"

        ' TODO: handle the load commands by authority code...
        Private _moduleCommands As ReadOnlyCollection(Of AuthorizedCommandViewModel)
        Public Property Commands() As ReadOnlyCollection(Of AuthorizedCommandViewModel)
            Get
                Return _moduleCommands
            End Get
            Private Set(ByVal value As ReadOnlyCollection(Of AuthorizedCommandViewModel))
                _moduleCommands = value
            End Set
        End Property

#End Region

#Region "Commands Handler"

        Private Sub ExecuteShowNailCategoryRepository()
            Dim workspace As New NailCategoryRepositoryViewModel()
            Me.Workspaces.Add(workspace)
            Me.SetActiveWorkspace(workspace)
        End Sub

        Private Sub ExecuteLogout()
            Me.OnUserLogout(EventArgs.Empty)
        End Sub

#End Region

#Region "Functions"

        Private Function ApplyCommands(ByVal authorityCode As Integer) As List(Of AuthorizedCommandViewModel)
            Dim commands As New List(Of AuthorizedCommandViewModel)

            Select Case authorityCode
                Case 1
                    commands = ( _
                        From command In Me.CreateCommands()
                        Where command.Group = CommandGroup.All OrElse command.Group = CommandGroup.Admin
                        Select command).ToList()
                Case Else
                    commands = ( _
                        From command In Me.CreateCommands()
                        Where command.Group = CommandGroup.All
                        Select command).ToList()
            End Select

            Return commands
        End Function

        Private Function CreateCommands() As List(Of AuthorizedCommandViewModel)
            Dim commands As New List(Of AuthorizedCommandViewModel)
            commands.Add(New AuthorizedCommandViewModel(StringResources.COMMAND_SHOW_NAILCATEGORYREPOSITORY, CommandGroup.Admin, New SimpleCommand(AddressOf Me.ExecuteShowNailCategoryRepository)))
            commands.Add(New AuthorizedCommandViewModel(StringResources.COMMAND_LOGOUT, CommandGroup.All, New SimpleCommand(AddressOf Me.ExecuteLogout)))

            Return commands
        End Function

        Private Sub SetActiveWorkspace(ByVal workspace As SubWorkspaceViewModel)
            Dim workspacesView As ICollectionView = CollectionViewSource.GetDefaultView(Me.Workspaces)
            If workspacesView IsNot Nothing Then
                workspacesView.MoveCurrentTo(workspace)
            End If

            Me.ActiveWorkspace = workspace
        End Sub

#End Region

    End Class
End Namespace
